#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>

#include <sqlite3.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <pthread.h>

#include "./include/unicom.h"
#include "./include/define.h"
#include "./include/ipc.h"
#include "./include/tty.h"
#include "./include/uart.h"
#include "./include/display_env.h"
#include "./include/display_goods.h"
#include "../include/web_ctrl_m0.h"

#include "../include/advance_setting.h"

int fd;
struct sendEnv house_env;
struct ipc_info ipc_info;

void *advance_setting(void *arg)
{
	//int ret;
	struct msg msg_buf;

	init_advance_msg(&ipc_info);

	while (1)
	{
		memset(&msg_buf, 0, sizeof(struct msg));
		get_advance_msg(&ipc_info, &msg_buf);
		set_advance_info(&msg_buf);
	}

	pthread_exit("pthread advance_setting exit!");
}

void *get_info(void *arg)
{
	int ret;

	puts("Init shm...");
	if (0 > init_shm(&ipc_info))
	{ //初始化共享内存
		fprintf(stderr, "init_shm error\n");
		exit(-1);
	}

	while (1)
	{
		bzero(&house_env, sizeof(struct sendEnv));
		ret = read(fd, &house_env, 4);
		if (0 > ret)
		{
			perror("read");
			break;
		}
		else if (ret != 4)
		{
			continue;
		}

		if (house_env.type == 'e')
		{
			ret = read(fd, (char *)&house_env + 4, sizeof(struct sendEnv) - 4);
			if (house_env.temp[0] >= 10)
			{
				display_env(&house_env);
				show_env2web(&ipc_info, &house_env);
			}
		}
		else if (house_env.type == 'r')
		{
			ret = read(fd, (char *)&house_env + 4, sizeof(struct sendGoods) - 4);
			display_rfid((struct sendGoods *)&house_env);
			write_rfid2sql((struct sendGoods *)&house_env);
		}
		else
		{
			fprintf(stderr, "Error: house_env.type ret = %d\n", ret);
		}
	}

	pthread_exit("pthread get_info exit!");
}

void *deal_cmd(void *arg)
{
	int ret;

	puts("Init msg...");
	if (0 > init_msg_queue(&ipc_info))
	{ //初始化消息队列
		fprintf(stderr, "Init_msg_queue error\n");
		exit(-1);
	}

	while (1)
	{
		ret = web_ctl_m0(fd, &ipc_info);
		if (ret < 0)
		{
			fprintf(stderr, "Error: web_ctl_m0 error\n");
		}
		fprintf(stderr, "* A msg was deal *\n");
	}

	pthread_exit("pthread deal_cmd exit!");
}

int open_loop(const char *dev_path)
{
	int fd;
	int i;
	char dev[64] = {0};

	while (1)
	{
		for (i = 0; i < 7; i++)
		{
			memset(dev, 0, sizeof(dev));
			sprintf(dev, "%s%d", dev_path, i);

			fprintf(stderr, "Trying to open %s...\n", dev);

			fd = open(dev, O_RDWR);
			if (0 > fd)
			{
				continue;
			}
			else
			{
				fprintf(stderr, "Open %s OK.\n", dev);
				return fd;
			}
		}
		fprintf(stderr, "Waitting for trying again\n");
		sleep(2);
	}
	return fd;
}

int main(int argc, char **argv)
{
	//int ret;

	if (2 != argc)
	{
		fprintf(stderr, "Usage: %s <device_node>\n    For example: %s /dev/ttyUSB\n", argv[0], argv[0]);
		return -1;
	}

	puts("Open...");
	fd = open_loop(argv[1]);

	puts("Init uart...");
	if (0 > init_uart(fd, BAUDRATE, 8, 1, 'N'))
	{ //初始化串口
		fprintf(stderr, "uart init error\n");
		return -1;
	}

	memset(&ipc_info, 0, sizeof(struct ipc_info));

	/*
	 *线程1 消息接收 接收M0发到串口的数据，在网页显示
	 **/
	pthread_t info_thread;
	pthread_attr_t info_thread_attr;
	pthread_attr_init(&info_thread_attr);

	if (0 != pthread_create(&info_thread, NULL, //&info_thread_attr,
							get_info, NULL))
	{
		fprintf(stderr, "Error: info_thread pthread_create error\n");
		exit(-1);
	}

	/*
	 *线程2 远程控制 命令处理 阻塞读取消息队列中cgi发来的消息
	 **/
	pthread_t cmd_thread;
	pthread_attr_t cmd_thread_attr;
	pthread_attr_init(&cmd_thread_attr);

	if (0 != pthread_create(&cmd_thread, NULL, //&cmd_thread_attr,
							deal_cmd, NULL))
	{
		fprintf(stderr, "Error: cmd_thread pthread_create error\n");
		exit(-1);
	}

	/*
	 *线程3 高级设置
	 **/
	pthread_t advance_thread;
	pthread_attr_t advance_thread_attr;
	pthread_attr_init(&advance_thread_attr);

	if (0 != pthread_create(&advance_thread, NULL, //&advance_thread_attr,
							advance_setting, NULL))
	{
		fprintf(stderr, "Error: advance_thread pthread_create error\n");
		exit(-1);
	}

	while (1)
	{
		sleep(10);
	}

	return 0;
}
